const { dbCmd, verifyCollection } = require("../../common/constants");
const { ERROR } = require("../../common/error");
const { getVerifyCode } = require("../../common/utils");

async function setVerifyCode({ mobile, email, code, expiresIn, scene } = {}) {
  const now = Date.now();
  const record = {
    mobile,
    email,
    scene,
    code: code || getVerifyCode(),
    state: 0,
    ip: this.getUniversalClientInfo().clientIP,
    created_date: now,
    expired_date: now + expiresIn * 1000,
  };
  await verifyCollection.add(record);
  return {
    errCode: 0,
  };
}

async function setEmailVerifyCode({ email, code, expiresIn, scene } = {}) {
  email = email && email.trim();
  if (!email) {
    throw {
      errCode: ERROR.INVALID_EMAIL,
    };
  }
  email = email.toLowerCase();
  return setVerifyCode.call(this, {
    email,
    code,
    expiresIn,
    scene,
  });
}

async function setMobileVerifyCode({ mobile, code, expiresIn, scene } = {}) {
  mobile = mobile && mobile.trim();
  if (!mobile) {
    throw {
      errCode: ERROR.INVALID_MOBILE,
    };
  }
  return setVerifyCode.call(this, {
    mobile,
    code,
    expiresIn,
    scene,
  });
}

async function verifyEmailCode({ email, code, scene } = {}) {
  email = email && email.trim();
  if (!email) {
    throw {
      errCode: ERROR.INVALID_EMAIL,
    };
  }
  email = email.toLowerCase();
  const { data: codeRecord } = await verifyCollection
    .where({
      email,
      scene,
      code,
      state: 0,
      expired_date: dbCmd.gt(Date.now()),
    })
    .limit(1)
    .get();

  if (codeRecord.length === 0) {
    throw {
      errCode: ERROR.EMAIL_VERIFY_CODE_ERROR,
    };
  }
  await verifyCollection.doc(codeRecord[0]._id).update({
    state: 1,
  });
  return {
    errCode: 0,
  };
}

async function verifyMobileCode({ mobile, code, scene } = {}) {
  mobile = mobile && mobile.trim();
  if (!mobile) {
    throw {
      errCode: ERROR.INVALID_MOBILE,
    };
  }
  const { data: codeRecord } = await verifyCollection
    .where({
      mobile,
      scene,
      code,
      state: 0,
      expired_date: dbCmd.gt(Date.now()),
    })
    .limit(1)
    .get();

  if (codeRecord.length === 0) {
    throw {
      errCode: ERROR.MOBILE_VERIFY_CODE_ERROR,
    };
  }

  await verifyCollection.doc(codeRecord[0]._id).update({
    state: 1,
  });
  return {
    errCode: 0,
  };
}

module.exports = {
  verifyEmailCode,
  verifyMobileCode,
  setEmailVerifyCode,
  setMobileVerifyCode,
};
